www.gusucode.com > VC 模范QQ做的一个界面-源码程序 > VC 模范QQ做的一个界面-源码程序/code/MyQQ/TreeCtrlST.cpp
//Download by http://www.NewXing.com // TreeCtrlST.cpp : implementation file // #include "stdafx.h" #include "MyQQ.h" #include "TreeCtrlST.h" #include "windowsx.h" // required for GET_X_LPARAM, GET_Y_LPARAM) #ifdef _DEBUG #define new DEBUG_NEW #undef THIS_FILE static char THIS_FILE[] = __FILE__; #endif ///////////////////////////////////////////////////////////////////////////// // CTreeCtrlST CTreeCtrlST::CTreeCtrlST() { BgColor = RGB(255, 255, 255); FontColor = RGB(0, 0, 0); m_bBgStretch = FALSE; } CTreeCtrlST::~CTreeCtrlST() { if( m_bitmap.m_hObject != NULL ) m_bitmap.DeleteObject(); if( m_pal.m_hObject != NULL ) m_pal.DeleteObject(); } BEGIN_MESSAGE_MAP(CTreeCtrlST, CTreeCtrl) //{{AFX_MSG_MAP(CTreeCtrlST) ON_WM_DRAWITEM() ON_WM_ERASEBKGND() ON_WM_PAINT() ON_WM_PALETTECHANGED() ON_WM_SIZE() ON_WM_QUERYNEWPALETTE() ON_WM_HSCROLL() ON_WM_VSCROLL() ON_NOTIFY_REFLECT(NM_CLICK, OnClick) ON_WM_LBUTTONDOWN() ON_WM_LBUTTONUP() ON_WM_MOVING() //}}AFX_MSG_MAP END_MESSAGE_MAP() ///////////////////////////////////////////////////////////////////////////// // CTreeCtrlST message handlers void CTreeCtrlST::OnDrawItem(int nIDCtl, LPDRAWITEMSTRUCT lpDrawItemStruct) { // TODO: Add your message handler code here and/or call default CTreeCtrl::OnDrawItem(nIDCtl, lpDrawItemStruct); } BOOL CTreeCtrlST::OnEraseBkgnd(CDC* pDC) { // TODO: Add your message handler code here and/or call default if( m_bitmap.m_hObject != NULL ) return TRUE; return CTreeCtrl::OnEraseBkgnd(pDC); } void CTreeCtrlST::DrawItemText(CDC *pDC, CString text, CRect rect, int nFormat) { UINT nStyle = DT_VCENTER | DT_SINGLELINE; if (nFormat == LVCFMT_LEFT) nStyle |= DT_LEFT; else if (nFormat == LVCFMT_CENTER) nStyle |= DT_CENTER; else // nFormat == LVCFMT_RIGHT nStyle |= DT_RIGHT; if((text.GetLength()>0) && (rect.right>rect.left)) { pDC->DrawText (text, rect, nStyle); } } void CTreeCtrlST::OnItemexpanding(NMHDR *pNMHDR, LRESULT *pResult) { NM_TREEVIEW* pNMTreeView = (NM_TREEVIEW*)pNMHDR; if( m_bitmap.m_hObject != NULL ) InvalidateRect(NULL); *pResult = 0; } void CTreeCtrlST::OnPaint() { CPaintDC dc(this); // device context for painting // TODO: Add your message handler code here CRect rcClip, rcClient; dc.GetClipBox( &rcClip ); GetClientRect(&rcClient); // Create a compatible memory DC CDC memDC; memDC.CreateCompatibleDC( &dc ); // Select a compatible bitmap into the memory DC CBitmap bitmap, bmpImage; bitmap.CreateCompatibleBitmap( &dc, rcClient.Width(), rcClient.Height() ); CBitmap *OldBitmap = memDC.SelectObject( &bitmap ); // First let the control do its default drawing. CTreeCtrl::DefWindowProc( WM_PAINT, (WPARAM)memDC.m_hDC, 0 ); /* // create the font CFont *pFontDC; CFont fontDC, boldFontDC; LOGFONT logfont; CFont *pFont = GetFont(); pFont->GetLogFont( &logfont ); fontDC.CreateFontIndirect( &logfont ); //普通字体 pFontDC = memDC.SelectObject( &fontDC ); logfont.lfWeight = 700; boldFontDC.CreateFontIndirect( &logfont ); //粗体字 // and now let's get to the painting itself HTREEITEM hItem = GetFirstVisibleItem(); int n = GetVisibleCount(); hItem = GetFirstVisibleItem(); n = GetVisibleCount(); while(hItem!=NULL && n>=0) { CRect rect; CRect m_labelRect; UINT selflag = TVIS_SELECTED ; // |TVIS_DROPHILITED; CString ItemText = GetItemText(hItem); GetItemRect( hItem, &m_labelRect, TRUE ); //文字 GetItemRect( hItem, &rect, FALSE ); if ( !(GetItemState( hItem, selflag ) & selflag )) //选中状态 { memDC.SetBkMode(TRANSPARENT); memDC.SetTextColor(::GetSysColor (COLOR_WINDOWTEXT )); DrawItemText(&memDC,ItemText,m_labelRect,LVCFMT_LEFT); } else { COLORREF m_highlightColor = ::GetSysColor (COLOR_HIGHLIGHT); CBrush brush(m_highlightColor); memDC.FillRect (m_labelRect, &brush); // draw a dotted focus rectangle memDC.DrawFocusRect (m_labelRect); memDC.SetBkColor(m_highlightColor); memDC.SetTextColor(::GetSysColor (COLOR_HIGHLIGHTTEXT)); memDC.SelectObject( &boldFontDC ); DrawItemText(&memDC,ItemText,m_labelRect,LVCFMT_LEFT); memDC.SelectObject( &pFontDC ); } hItem = GetNextVisibleItem( hItem ); n--; } memDC.SelectObject( pFontDC ); */ // Draw bitmap in the background if one has been set if( m_bitmap.m_hObject != NULL ) { // Now create a mask CDC maskDC; maskDC.CreateCompatibleDC(&dc); CBitmap maskBitmap; // Create monochrome bitmap for the mask maskBitmap.CreateBitmap( rcClient.Width(), rcClient.Height(), 1, 1, NULL ); CBitmap *OldMask = maskDC.SelectObject( &maskBitmap ); memDC.SetBkColor( ::GetSysColor( COLOR_WINDOW ) ); // Create the mask from the memory DC maskDC.BitBlt( 0, 0, rcClient.Width(), rcClient.Height(), &memDC, rcClient.left, rcClient.top, SRCCOPY ); CDC tempDC; tempDC.CreateCompatibleDC(&dc); CBitmap *Oldtemp = tempDC.SelectObject( &m_bitmap ); CDC imageDC; CBitmap bmpImage; imageDC.CreateCompatibleDC( &dc ); bmpImage.CreateCompatibleBitmap( &dc, rcClient.Width(), rcClient.Height() ); CBitmap *OldImage = imageDC.SelectObject( &bmpImage ); if( dc.GetDeviceCaps(RASTERCAPS) & RC_PALETTE && m_pal.m_hObject != NULL ) { dc.SelectPalette( &m_pal, FALSE ); dc.RealizePalette(); imageDC.SelectPalette( &m_pal, FALSE ); } // Get x and y offset CRect rcRoot; GetItemRect(GetRootItem(), rcRoot, FALSE ); rcRoot.left = -GetScrollPos( SB_HORZ ); imageDC.FillSolidRect(CRect(0,0,rcClient.right,rcClient.bottom),BgColor); if( m_bBgStretch ) { imageDC.SetStretchBltMode(COLORONCOLOR); imageDC.StretchBlt( 0,0,rcClient.right,rcClient.bottom, &tempDC, 0,0,m_cxBitmap,m_cyBitmap, SRCCOPY ); } else { imageDC.BitBlt( rcClient.right-m_cxBitmap,rcClient.bottom-m_cyBitmap, m_cxBitmap,m_cyBitmap, &tempDC, 0, 0, SRCCOPY ); /* // Draw bitmap in tiled manner to imageDC for( int i = rcRoot.left; i < rcClient.right; i += m_cxBitmap ) for( int j = rcRoot.top; j < rcClient.bottom; j += m_cyBitmap ) { imageDC.BitBlt( i, j, m_cxBitmap, m_cyBitmap, &tempDC,0, 0, SRCCOPY ); } */ } // Set the background in memDC to black. Using SRCPAINT with black and any other // color results in the other color, thus making black the transparent color memDC.SetBkColor(RGB(0,0,0)); memDC.SetTextColor(RGB(255,255,255)); memDC.BitBlt( rcClip.left, rcClip.top, rcClip.Width(), rcClip.Height(), &maskDC, rcClip.left, rcClip.top, SRCAND); // Set the foreground to black. See comment above. imageDC.SetBkColor(RGB(255,255,255)); imageDC.SetTextColor(RGB(0,0,0)); imageDC.BitBlt( rcClip.left, rcClip.top, rcClip.Width(), rcClip.Height(), &maskDC, rcClip.left, rcClip.top, SRCAND); // Combine the foreground with the background imageDC.BitBlt( rcClip.left, rcClip.top, rcClip.Width(), rcClip.Height(), &memDC, rcClip.left, rcClip.top, SRCPAINT); // Draw the final image to the screen dc.BitBlt( rcClip.left, rcClip.top, rcClip.Width(), rcClip.Height(), &imageDC, rcClip.left, rcClip.top, SRCCOPY ); //释放对象 maskDC.SelectObject(OldMask); imageDC.SelectObject(OldImage); tempDC.SelectObject(Oldtemp); maskBitmap.DeleteObject(); bmpImage.DeleteObject(); maskDC.DeleteDC(); imageDC.DeleteDC(); tempDC.DeleteDC(); } else { dc.BitBlt( rcClip.left, rcClip.top, rcClip.Width(), rcClip.Height(), &memDC, rcClip.left, rcClip.top, SRCCOPY ); } memDC.SelectObject(OldBitmap); bitmap.DeleteObject(); memDC.DeleteDC(); // Do not call CTreeCtrl::OnPaint() for painting messages } void CTreeCtrlST::OnPaletteChanged(CWnd* pFocusWnd) { CTreeCtrl::OnPaletteChanged(pFocusWnd); // TODO: Add your message handler code here if( pFocusWnd == this ) return; CTreeCtrl::OnPaletteChanged(pFocusWnd); } void CTreeCtrlST::OnSize(UINT nType, int cx, int cy) { CTreeCtrl::OnSize(nType, cx, cy); // TODO: Add your message handler code here Invalidate(); } void CTreeCtrlST::PreSubclassWindow() { // TODO: Add your specialized code here and/or call the base class CTreeCtrl::PreSubclassWindow(); } BOOL CTreeCtrlST::SetBkImage(HBITMAP hBmp) { if( m_bitmap.m_hObject != NULL ) m_bitmap.DeleteObject(); if( m_pal.m_hObject != NULL ) m_pal.DeleteObject(); if( hBmp == NULL ) return FALSE; m_bitmap.Attach( hBmp ); BITMAP bm; m_bitmap.GetBitmap( &bm ); m_cxBitmap = bm.bmWidth; m_cyBitmap = bm.bmHeight; // Create a logical palette for the bitmap DIBSECTION ds; BITMAPINFOHEADER &bmInfo = ds.dsBmih; m_bitmap.GetObject( sizeof(ds), &ds ); int nColors = bmInfo.biClrUsed ? bmInfo.biClrUsed : 1 << bmInfo.biBitCount; // Create a halftone palette if colors > 256. CClientDC dc(NULL); // Desktop DC if( nColors > 256 ) m_pal.CreateHalftonePalette( &dc ); else { // Create the palette RGBQUAD *pRGB = new RGBQUAD[nColors]; CDC memDC; memDC.CreateCompatibleDC(&dc); memDC.SelectObject( &m_bitmap ); ::GetDIBColorTable( memDC, 0, nColors, pRGB ); UINT nSize = sizeof(LOGPALETTE) + (sizeof(PALETTEENTRY) * nColors); LOGPALETTE *pLP = (LOGPALETTE *) new BYTE[nSize]; pLP->palVersion = 0x300; pLP->palNumEntries = nColors; for( int i=0; i < nColors; i++) { pLP->palPalEntry[i].peRed = pRGB[i].rgbRed; pLP->palPalEntry[i].peGreen = pRGB[i].rgbGreen; pLP->palPalEntry[i].peBlue = pRGB[i].rgbBlue; pLP->palPalEntry[i].peFlags = 0; } m_pal.CreatePalette( pLP ); delete[] pLP; delete[] pRGB; } Invalidate(); return TRUE; } BOOL CTreeCtrlST::SetBkImage(LPCTSTR lpszResourceName) { HBITMAP hBmp = (HBITMAP)::LoadImage( AfxGetInstanceHandle(), lpszResourceName, IMAGE_BITMAP, 0,0, LR_CREATEDIBSECTION ); return SetBkImage(hBmp); } BOOL CTreeCtrlST::SetBkImage(UINT nIDResource) { return SetBkImage( (LPCTSTR)nIDResource ); } void CTreeCtrlST::SetBgStretch(BOOL Flag) { m_bBgStretch = Flag; } BOOL CTreeCtrlST::OnQueryNewPalette() { // TODO: Add your message handler code here and/or call default CClientDC dc(this); if( dc.GetDeviceCaps(RASTERCAPS) & RC_PALETTE && m_pal.m_hObject != NULL ) { dc.SelectPalette( &m_pal, FALSE ); BOOL result = dc.RealizePalette(); if( result ) Invalidate(); return result; } return CTreeCtrl::OnQueryNewPalette(); } void CTreeCtrlST::OnHScroll(UINT nSBCode, UINT nPos, CScrollBar* pScrollBar) { // TODO: Add your message handler code here and/or call default if( m_bitmap.m_hObject != NULL ) InvalidateRect(NULL); CTreeCtrl::OnHScroll(nSBCode, nPos, pScrollBar); } void CTreeCtrlST::OnVScroll(UINT nSBCode, UINT nPos, CScrollBar* pScrollBar) { // TODO: Add your message handler code here and/or call default if( m_bitmap.m_hObject != NULL ) InvalidateRect(NULL); CTreeCtrl::OnVScroll(nSBCode, nPos, pScrollBar); } BOOL CTreeCtrlST::PreTranslateMessage(MSG* pMsg) { // TODO: Add your specialized code here and/or call the base class /* //把单击动作当做双击处理 if(pMsg->message == WM_LBUTTONDOWN) { pMsg->message = WM_LBUTTONDBLCLK; } */ return CTreeCtrl::PreTranslateMessage(pMsg); } void CTreeCtrlST::OnClick(NMHDR* pNMHDR, LRESULT* pResult) { // TODO: Add your control notification handler code here /* DWORD dw = GetMessagePos(); // retrieve mouse cursor position when msg was sent CPoint pt(GET_X_LPARAM(dw), GET_Y_LPARAM(dw)); // ..and put into point structure ScreenToClient(&pt); UINT flags = 0; HTREEITEM it = HitTest(pt, &flags); // See where the click was on // if(it != NULL && nFlag == TVHT_ONITEMSTATEICON) if( //(flags & TVHT_ONITEMRIGHT) || (flags & TVHT_ONITEMINDENT) || (flags & TVHT_ONITEM)) { // HTREEITEM SelItem = GetSelectedItem(); // SetItemData(SelItem, DWORD(nFlag)); // GetItemData(SelItem); CString str = GetItemText(it); AfxMessageBox(str, MB_OK,0); } */ *pResult = 0; } void CTreeCtrlST::OnLButtonDown(UINT nFlags, CPoint point) { // TODO: Add your message handler code here and/or call default UINT flags = 0; HTREEITEM item = HitTest(point, &flags); if(item != NULL && (flags & TVHT_ONITEM)) //&& !ItemHasChildren(item)) { HTREEITEM itch = GetChildItem(item); if(itch == NULL) { // SelectItem(item); // CString str = GetItemText(item); // HWND hWnd = ((CMyQQApp*)AfxGetApp())->m_MainDlg; // ::PostMessage(hWnd, WM_SHOWINFO, LPARAM(item), 0); /* CUserInfoDlg* pUserDlg; pUserDlg = new CUserInfoDlg; pUserDlg->Create(IDD_INFORMATION, NULL);//GetParent()); pUserDlg->m_ShowText.Format("昵称: %s",str); pUserDlg->ShowWindow(SW_SHOW); */ } } CTreeCtrl::OnLButtonDown(nFlags, point); } void CTreeCtrlST::OnLButtonUp(UINT nFlags, CPoint point) { // TODO: Add your message handler code here and/or call default UINT flags = 0; HTREEITEM item = HitTest(point, &flags); if(item != NULL && (flags & TVHT_ONITEM)) //&& !ItemHasChildren(item)) { HTREEITEM itch = GetChildItem(item); if(itch == NULL) { SelectItem(item); CString str = GetItemText(item); HWND hWnd = ((CMyQQApp*)AfxGetApp())->m_MainDlg; ::PostMessage(hWnd, WM_SHOWINFO, LPARAM(item), 0); /* CUserInfoDlg* pUserDlg; pUserDlg = new CUserInfoDlg; pUserDlg->Create(IDD_INFORMATION, NULL);//GetParent()); pUserDlg->m_ShowText.Format("昵称: %s",str); pUserDlg->ShowWindow(SW_SHOW); */ } } CTreeCtrl::OnLButtonUp(nFlags, point); } void CTreeCtrlST::OnMoving(UINT fwSide, LPRECT pRect) { CTreeCtrl::OnMoving(fwSide, pRect); // TODO: Add your message handler code here // Invalidate(); }